import wx

import functools
import logging

import pyciv.actionpanel
import pyciv.mappanel
import pyciv.layers
import pyciv.hexagon
import pyciv.player
import pyciv.playerpanel
import pyciv.rules
import pyciv.scorepanel

class EndTurnStatus(object):
    def __init__(self):
        self.can_end_turn = True
        self.reason = ""
        
    def update(self, engine):
        (self.can_end_turn, self.reason) = engine.can_end_turn()


class MainFrame(wx.Frame):
    def __init__(self, engine):
        self.last_hex = None
        self.last_status_updater = None
        self.end_turn_status = EndTurnStatus()

        wx.Frame.__init__(self, None)
        self._engine = engine
        self._engine.create_default_state()

        self.mappanel = pyciv.mappanel.MapPanel(
            hexes=self._engine.state.hexes, 
            layers=[pyciv.layers.Terrain(self._engine.state),
                    pyciv.layers.Unit(self._engine.state),
                    pyciv.layers.Owner(self._engine.state),
                    pyciv.layers.Selected(self._engine)],
            parent=self, 
            size=(800, 600))

        self.SetInitialSize((800, 650))

        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetFieldsCount(3)
        self.endturn_button = wx.Button(self.mappanel, 
                                        wx.ID_ANY, 
                                        "End turn 0",
                                        pos=(660, 595),
                                        size=(130,30))
        self.player_panel = pyciv.playerpanel.PlayerPanel(
            self._engine.state.current_player,
            self._engine.current_player(),
            parent=self.mappanel,
            pos=(650, 0),
            size=(150,150))
        self.score_panel = pyciv.scorepanel.ScorePanel(
            parent=self.mappanel,
            pos=(650, 450),
            size=(150,140))
        self.action_panel = pyciv.actionpanel.ActionPanel(
            [], 
            self,
            parent=self.mappanel,
            pos=(150, 595),
            size=(500,35))
        self.endturn_button.Bind(wx.EVT_BUTTON, self.on_end_turn)
        self.endturn_button.Bind(wx.EVT_MOTION, self.on_button_motion)
        self.Bind(wx.EVT_MOUSEWHEEL, self.on_mouse_wheel)
        self.mappanel.Bind(wx.EVT_MOTION, self.on_mouse_motion)
        self.mappanel.Bind(wx.EVT_LEFT_UP, self.on_left_click)
        self.mappanel.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
        self.on_end_turn()

    def update_tooltip_status_bar(self, updater):
        if self.last_status_updater != updater:
            self.last_status_updater = updater
            self.statusbar.SetStatusText(updater.reason, 1)

    def on_button_motion(self, event):
        self.update_tooltip_status_bar(self.end_turn_status)

    def on_end_turn(self, event=None):
        try:
            self._engine.end_turn()
        except pyciv.engine.GameOver, gameover:
            wx.MessageBox(gameover.message)
        self.update()

    def _update_turn_button(self):
        self.end_turn_status.update(self._engine)
        self.endturn_button.Enable(self.end_turn_status.can_end_turn)
        self.endturn_button.SetLabel(
            "End Turn %d of %d" % 
            (self._engine.state.turn, pyciv.rules.TURN_LIMIT))
        self.update_tooltip_status_bar(self.end_turn_status)

    def on_left_click(self, event):
        hex = self.mappanel.get_hex(event.GetPositionTuple())
        if hex:
            self._engine.select(hex)
            self.update()
                              
    def on_right_click(self, event):
        self._engine.deselect()
        self.update()
            
    def execute_action(self, index):
        self._engine.execute_action(index)
        self.update()

    def display_action_tooltip(self, index):
        if index < len(self._engine.actions):
            self.update_tooltip_status_bar(self._engine.actions[index])
        else:
            self.update_tooltip_status_bar(pyciv.action.NONE)

    def on_mouse_wheel(self, event):
        hex = self.mappanel.get_hex(event.GetPositionTuple())
        if hex:
            pass

    def on_mouse_motion(self, event):
        hex = self.mappanel.get_hex(event.GetPositionTuple())
        if self.last_hex != hex:
            if hex:
                text = "Hex: %d %d %d" % (hex[0], hex[1], hex[2])
                if self._engine.state.supply[hex] > 0:
                    text += ",  Supply: %d" % self._engine.state.supply[hex]
                if self._engine.state.victory[hex] > 0:
                    text += ",  Victory location"
                self.statusbar.SetStatusText(text, 0)
                if self._engine.hex_action.has_key(hex):
                    self.update_tooltip_status_bar(self._engine.hex_action[hex])
                else:
                    self.statusbar.SetStatusText(
                        "Select hex", 1)
                self.statusbar.SetStatusText(str(self._engine.state.unit[hex]), 2)
            else:
                self.statusbar.SetStatusText(
                    "Hex: None", 0)
            self.last_hex = hex

    def update(self):
        self._update_turn_button()
        self.action_panel.update(self._engine.actions)
        self.mappanel.update()
        self.player_panel.update(self._engine.state.current_player,
                                 self._engine.current_player(),
                                 self._engine)
        self.score_panel.update(self._engine)
        self.SetFocus()

        
